<template>
  <div @click="choseFile">
    <slot name="button"></slot>
    <input ref="excel" :id="id" type="file" class="file-hide" accept=".xlsx, .xls, .csv" @change="handleFileChange">
  </div>
</template>

<script>
  const XLSX = window.XLSX

  export default {
    name: 'excel',
    props: {
      formatter: {
        type: Array,
        default: []
      }
    },
    data() {
      return {
        id: 'file-' + Math.ceil(Math.random() * 1024),
        rawFile: null
      }
    },
    methods: {
      choseFile() {
        document.getElementById(this.id).click()
      },
      async handleFileChange(e) {
        if (this.rawFile !== null) {
          return
        }

        this.rawFile = e.target.files[0]

        let workbook = await this.fileConvertToWorkbook(this.rawFile)
        let xlsxArr = XLSX.utils.sheet_to_json(workbook.Sheets[workbook.SheetNames[0]])
        let data = this.xlsxArrToTableArr(xlsxArr)

        this.rawFile = null
        this.$refs.excel.value = ''
        this.$emit('changeFile', data)
      },
      fileConvertToWorkbook (file) {
        let reader = new FileReader()
        let fixdata = (data) => {
          let o = "", l = 0, w = 10240
          for( ; l<data.byteLength/w ; ++l) {
            o += String.fromCharCode.apply(null,new Uint8Array(data.slice(l*w,l*w+w)))
          }
          o += String.fromCharCode.apply(null, new Uint8Array(data.slice(l*w)))
          return o
        }
        return new Promise((resolve, reject) => {
          try {
            reader.onload = (renderEvent) => {
              let data = renderEvent.target.result
              if(this.rABS) {
                /* if binary string, read with type 'binary' */
                resolve(XLSX.read(data, {type: 'binary'}))
              } else {
                /* if array buffer, convert to base64 */
                let arr = fixdata(data)
                resolve(XLSX.read(btoa(arr), {type: 'base64'}))
              }
            }
            reader.onerror = (error) => {
              reject(error)
            }
            if (this.rABS) {
              reader.readAsBinaryString(file)
            } else {
              reader.readAsArrayBuffer(file)
            }
          } catch (error) {
            reject(error)
          }
        })
      },
      xlsxArrToTableArr (xlsxArr) {
        let tableArr = []
        let length = 0
        let maxLength = 0
        let maxLengthIndex = 0

        xlsxArr.forEach((item, index) => {
          length = Object.keys(item).length
          if (maxLength < length) {
            maxLength = length
            maxLengthIndex = index
          }
        })

        let tableHeader = Object.keys(xlsxArr[maxLengthIndex])

        xlsxArr.forEach((item) => {
          let rowItem = {}

          for (let i = 0; i < maxLength; i++) {
            rowItem[this.formatter[i]] = item[tableHeader[i]] || ''
          }

          tableArr.push(rowItem)
        })
        return {
          header: tableHeader,
          data: tableArr
        }
      }
    }
  }
</script>

<style>
  .file-hide {display: none;}
</style>
